/* * Copyright 2015 Trento Rise. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package eu.trentorise.opendata.jackan.test.ckan; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import eu.trentorise.opendata.jackan.CheckedCkanClient; import eu.trentorise.opendata.jackan.CkanClient; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.charset.Charset; import java.util.Iterator; import org.apache.http.HttpEntity; import org.apache.http.HttpHost; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.mime.HttpMultipartMode; import org.apache.http.entity.mime.MultipartEntity; import org.apache.http.entity.mime.content.ByteArrayBody; import org.apache.http.entity.mime.content.StringBody; import org.apache.http.impl.client.DefaultHttpClient; /** * This client include features that probably... just don't work * * @author David Leoni * @since 0.4.1 */ class ExperimentalCkanClient extends CkanClient { private ExperimentalCkanClient(){ super(); } public ExperimentalCkanClient(String URL, String token) { super(URL, token); } /** * Returns a builder instance. The builder is not threadsafe and you can use * one builder instance to build only one client instance. */ public static CkanClient.Builder builder() { return CkanClient.newBuilder(new ExperimentalCkanClient()); } /** * Uploads a file using file storage api, which I think is deprecated. As of * Aug 2015, coesn't work neither with demo.ckan.org nor dati.trentino * * Adapted from * https://github.com/Ontodia/openrefine-ckan-storage-extension/blob/c99de78fd605c4754197668c9396cffd1f9a0267/src/org/deri/orefine/ckan/StorageApiProxy.java#L34 */ public String uploadFile(String fileContent, String fileLabel) { HttpResponse formFields = null; try { String filekey = null; HttpClient client = new DefaultHttpClient(); // get the form fields required from ckan storage // notice if you put '3/' it gives not found :-/ String formUrl = getCatalogUrl() + "/api/storage/auth/form/file/" + fileLabel; HttpGet getFormFields = new HttpGet(formUrl); getFormFields.setHeader("Authorization", getCkanToken()); formFields = client.execute(getFormFields); HttpEntity entity = formFields.getEntity(); if (entity != null) { ByteArrayOutputStream os = new ByteArrayOutputStream(); entity.writeTo(os); //now parse JSON //JSONObject obj = new JSONObject(os.toString()); JsonNode obj = new ObjectMapper().readTree(os.toString()); //post the file now String uploadFileUrl = getCatalogUrl() + obj.get("action").asText(); HttpPost postFile = new HttpPost(uploadFileUrl); postFile.setHeader("Authorization", getCkanToken()); MultipartEntity mpEntity = new MultipartEntity(HttpMultipartMode.STRICT); //JSONArray fields = obj.getJSONArray("fields"); Iterator<JsonNode> fields = obj.get("fields").elements(); while (fields.hasNext()) { JsonNode fieldObj = fields.next(); //JSONObject fieldObj = fields.getJSONObject(i); String fieldName = fieldObj.get("name").asText(); String fieldValue = fieldObj.get("value").asText(); if (fieldName.equals("key")) { filekey = fieldValue; } mpEntity.addPart(fieldName, new StringBody(fieldValue, "multipart/form-data", Charset.forName("UTF-8"))); } /* for (int i = 0; i < fields.length(); i++) { //JSONObject fieldObj = fields.getJSONObject(i); JSONObject fieldObj = fields.getJSONObject(i); String fieldName = fieldObj.getString("name"); String fieldValue = fieldObj.getString("value"); if (fieldName.equals("key")) { filekey = fieldValue; } mpEntity.addPart(fieldName, new StringBody(fieldValue, "multipart/form-data", Charset.forName("UTF-8"))); } */ // assure that we got the file key if (filekey == null) { throw new RuntimeException("failed to get the file key from CKAN storage form API. the response from " + formUrl + " was: " + os.toString()); } //the file should be the last part //hack... StringBody didn't work with large files mpEntity.addPart("file", new ByteArrayBody(fileContent.getBytes(Charset.forName("UTF-8")), "multipart/form-data", fileLabel)); postFile.setEntity(mpEntity); HttpResponse fileUploadResponse = client.execute(postFile); //check if the response status code was in the 200 range if (fileUploadResponse.getStatusLine().getStatusCode() < 200 || fileUploadResponse.getStatusLine().getStatusCode() >= 300) { throw new RuntimeException("failed to add the file to CKAN storage. response status line from " + uploadFileUrl + " was: " + fileUploadResponse.getStatusLine()); } return getCatalogUrl() + "/storage/f/" + filekey; //return CKAN_STORAGE_FILES_BASE_URI + filekey; } throw new RuntimeException("failed to get form details from CKAN storage. response line was: " + formFields.getStatusLine()); } catch (IOException ioe) { throw new RuntimeException("failed to upload file to CKAN Storage ", ioe); } } public static ExperimentalCkanClient of(CkanClient client) { return new ExperimentalCkanClient(client.getCatalogUrl(), client.getCkanToken()); } }